package com.panshi.repast.ImageCache;

import java.util.Collections;
import java.util.LinkedList;
import java.util.List;

import android.graphics.Bitmap;
import android.os.Handler;
import android.os.Handler.Callback;
import android.os.Looper;
import android.os.Message;

import com.panshi.repast.Http.HttpClientExecutor;

/**
 * 数据异步加载，获取图片
 * 
 */
public class ImageLoader implements Callback {

	private static ImageLoader mInstance = null;
	private static final int MAX_TASK_LIMIT = 1;
	private volatile int mActiveTaskCount;
	private final List<ImageRequest> mRequests; // 保存客户端请求信�?
	private final Handler mImageHandler;

	private ImageLoader() {
		mRequests = Collections
				.synchronizedList(new LinkedList<ImageRequest>());
		mImageHandler = new Handler(Looper.getMainLooper(), this);
	}

	/**
	 * 获得实例的唯全局访问点，单列模式
	 * 
	 * @return
	 */
	public static ImageLoader getInstance() {
		if (mInstance == null) {
			// 增加类锁,保证只初始化一次
			synchronized (ImageLoader.class) {
				if (mInstance == null) {
					mInstance = new ImageLoader();
				}
			}
		}
		return mInstance;
	}

	/**
	 * UI层回调数据接口方法
	 * 
	 * @param mDefValue
	 *            默认参数，作为控制
	 * 
	 */
	public Bitmap loadBitmap(String imageUrl, ImageCallback callback) {
		Bitmap bm = CacheMemUtil.getImage(imageUrl); // 查看是否在本地
		if (bm != null) {
			callback.imageLoaded(bm);
		} else {
			ImageRequest request = new ImageRequest(callback, imageUrl); // 网络加载
			insertRequestAtFrontOfQueue(request);
		}
		return bm;
	}

	/**
	 * 刷新任务队列
	 */
	private synchronized void flushRequests() {
		while (mActiveTaskCount < MAX_TASK_LIMIT && !mRequests.isEmpty()) {
			mActiveTaskCount++;
			ImageRequest request = mRequests.get(0);
			mRequests.remove(0);
			new RequestTast(request).start();
		}
	}

	/**
	 * 把任务请求加入任务队列头
	 * 
	 * @param request
	 */
	private void insertRequestAtFrontOfQueue(ImageRequest request) {
		// mRequests.add(0, request);
		mRequests.add(request);
		flushRequests();
	}

	/**
	 * 和服务器交互线程
	 * 
	 * @author
	 * 
	 */
	private class RequestTast extends Thread {

		private ImageRequest request;

		public RequestTast(ImageRequest request) {
			this.request = request;
		}

		@Override
		public void run() {
			try {
				onPreExecute();
				doInBackground();
			} catch (Exception e) {
				handleMessage(request);
			} finally {
				onPostExecute();
			}
		}

		/**
		 * 预处理任务
		 */
		protected void onPreExecute() {

		}

		/**
		 * 任务执行完成后，当前执行数减1，并刷新任务队列
		 */
		protected void onPostExecute() {
			mActiveTaskCount--;
			flushRequests();
		}

		/**
		 * 核心执行方法
		 * 
		 * @throws Exception
		 */
		protected void doInBackground() throws Exception {
			Bitmap bm = CacheMemUtil.getImage(request.url);
			// 网络加载
			if (bm == null) {
				byte[] data = HttpClientExecutor.getInstance().executeGet(
						request.url);
				if (data != null) {
					CacheMemUtil.putImage(request.url, data);
				}
				bm = CacheMemUtil.getImageFromCache(request.url);
			}
			request.bm = bm;
			handleMessage(request);
		}

	}

	/**
	 * 清除请求队列中的任务
	 */
	public void clearImageRequests() {
		mRequests.clear();
	}

	/**
	 * 向UI层发送消息
	 * 
	 * @param ImageRequest
	 *            请求参数
	 * @param mValue
	 *            请求返回的内容
	 */
	private void handleMessage(ImageRequest request) {
		// LoggerUtil.d(TAG, "图片请求返回:" + " url:" + request.url);
		Message msg = mImageHandler.obtainMessage();
		msg.obj = request;
		msg.sendToTarget(); // 向UI层发送数据

	}

	/**
	 * 通过回调函数，数据分发
	 */
	@Override
	public boolean handleMessage(Message msg) {
		ImageRequest request = (ImageRequest) msg.obj;
		if (request.callback != null
				&& request.callback instanceof ImageCallback) {
			// 向UI层传输回传的数据
			request.callback.imageLoaded(request.bm);
		}
		return false;
	}

	// 对外界开放的回调接口
	public interface ImageCallback {
		// 注意 此方法是用来设置目标对象的图像资源
		public void imageLoaded(Bitmap bm);
	}
}